//=============================================================================
/**
 *
 *	@file		evt_cats.c
 *	@brief		CATS系 便利関数
 *	@author		hosaka genya
 *	@data		2008.10.03
 *
 */
//=============================================================================
#include "common.h"
#include "system/arc_util.h"
#include "system/clact_tool.h"
#include "system/gra_tool.h"
#include "poketool/poke_tool.h"
#include "poketool/pokeicon.h"

#include "../poke_clact_def.h"
#include "evt_cats.h"

#include "data/mmodel/mmodel.naix"

//=============================================================================
/**
 *								定数定義
 */
//=============================================================================

//=============================================================================
/**
 *								構造体定義
 */
//=============================================================================

//=============================================================================
/**
 *							プロトタイプ宣言
 */
//=============================================================================
// -- prototype --
static void CATS_PokeGraTransCore( CATS_ACT_PTR p_cap, const MONS_INFO* p_mons, BOOL b_LCD_main, BOOL b_gray, HEAPID heapID, BOOL b_trans_pltt );
static void OBJ_CgxChangeTransShiftVramOfs( CLACT_WORK_PTR act, u8 * buf, u32 siz, u32 VramOfs );
static void OBJ_CgxChangeTrans( CLACT_WORK_PTR act, u8 * buf, u32 siz );
static void OBJ_PokeGraPlttTrans( CATS_ACT_PTR p_cap, u32 arc_no, u32 pal_idx, BOOL b_LCD_main, BOOL b_gray, HEAPID heapID );


//=============================================================================
/**
 *								外部公開関数
 */
//=============================================================================

//-----------------------------------------------------------------------------
/**
 *	@brief	CAPの参照先CGXにマップキャラのグラフィックを展開
 *
 *	@param	CATS_ACT_PTR cap
 *	@param	tex_idx
 *	@param	ptn_ofs
 *	@param	HeapID
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
void CATS_MapModelDraw( CATS_ACT_PTR cap, u32 tex_idx, u8 ptn_ofs, HEAPID HeapID )
{
	CLACT_MapModelTrans( cap->act, tex_idx, ptn_ofs, HeapID );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	CLACTの参照先CGXにマップキャラのグラフィックを展開
 *
 *	@param	CLACT_WORK_PTR act
 *	@param	tex_idx
 *	@param	ptn_ofs
 *	@param	HeapID
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
void CLACT_MapModelTrans( CLACT_WORK_PTR act, u32 tex_idx, u8 ptn_ofs, HEAPID HeapID )
{
	enum {
		TRANS_PAL_SIZE = 16*2,
		TRANS_CHR_X = 4,
		TRANS_CHR_Y = 4,
		TRANS_SIZE = TRANS_CHR_X * TRANS_CHR_Y * 0x20,
	};

	u32				i;
	ARCHANDLE*		arc;
	NNSG3dResTex*	pTex;
	void*			pFile;
	u8*				pStart;
	void*			pRawData;
	NNSG3dResDictTexData* pDictTex;

	// 非表示にしておく
	CATS_ObjectEnable( act, FALSE );

	//トレーナーデータのアーカイブオープン
	arc = ArchiveDataHandleOpen( ARC_MMODEL, HeapID );

	// テクスチャファイルを取得
	pFile = ArchiveDataLoadAllocByHandle( arc, tex_idx ,HeapID );
	pTex = NNS_G3dGetTex( (NNSG3dResFileHeader*)pFile );
	pDictTex = NNS_G3dGetTexDataByIdx( pTex, ptn_ofs );

	//テクスチャロウデータ取得
	{
		void* pBuf;
		u32 offset = (pDictTex->texImageParam & NNS_G3D_TEXIMAGE_PARAM_TEX_ADDR_MASK)<<3;

		HOSAKA_PRINT( "tex size = %d \n", pTex->texInfo.sizeTex );

		pStart = (u8*)pTex + pTex->texInfo.ofsTex;

		pBuf = sys_AllocMemoryLo( HeapID, TRANS_SIZE );

//		pRawData = &pStart[ TRANS_SIZE * ptn_ofs ];
		pRawData = &pStart[ offset ];
		ChangesInto_RawData_1D_from_2D( pRawData, TRANS_CHR_X, 0, 0, TRANS_CHR_X, TRANS_CHR_Y, pBuf );
		OBJ_CgxChangeTrans( act, pBuf, TRANS_SIZE );

		sys_FreeMemoryEz( pBuf );
	}

	//パレットロウデータ取得
	{
		NNSG2dImagePaletteProxy* ipp;
		NNS_G2D_VRAM_TYPE type;
		u32 vram;

		type = CLACT_VramTypeGet( act );

		pStart = (u8*)pTex + pTex->plttInfo.ofsPlttData;
		DC_FlushRange( pStart, TRANS_PAL_SIZE );

		ipp = CLACT_PaletteProxyGet( act );
		vram = NNS_G2dGetImagePaletteLocation( ipp, type );

		if( type == NNS_G2D_VRAM_TYPE_2DMAIN )
		{
			GX_LoadOBJPltt( pStart, vram, TRANS_PAL_SIZE );
		}
		else
		{
			GXS_LoadOBJPltt( pStart, vram, TRANS_PAL_SIZE );
		}
	}

	// -- 開放処理 --
	sys_FreeMemoryEz( pFile );
	ArchiveDataHandleClose( arc );

	// 表示
	CATS_ObjectEnable( act, TRUE );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	CAPの参照先CGXに主人公のグラフィックを展開
 *
 *	@param	CATS_ACT_PTR* ppCap
 *	@param	work
 *	@param	idx
 *	@param	seq
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
void CATS_HeroDraw( CATS_ACT_PTR* ppCap, PKTHLN_PTR work, u8 idx, u32 seq )
{
	CLACT_HeroTrans( ppCap[ idx ]->act, work, idx, seq );
}

void CLACT_HeroTrans( CLACT_WORK_PTR act, PKTHLN_PTR work, u8 idx, u32 seq )
{
	u32 tex_idx;
	MYSTATUS* pSt = PTFrame_GetMyStatus( work, idx );
	HEAPID HeapID = PTFrame_GetHeapID( work );

	// 男女判定
	if ( MyStatus_GetMySex( pSt ) == PM_MALE )
	{
		tex_idx = CATS_GetMapModelTexIdx( 0 );
	}
	else
	{
		tex_idx = CATS_GetMapModelTexIdx( 1 );
	}

	CLACT_MapModelTrans( act, tex_idx , seq, HeapID );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	テクスチャのIDXを取得
 *
 *	@param	u8 tex_idx
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
u16 CATS_GetMapModelTexIdx( u8 tex_idx )
{
	enum{ TEX_IDX_MAX = 6, };

	static const TexIdxTbl[ TEX_IDX_MAX ] =
	{
		NARC_mmodel_pkthhero_nsbtx,
		NARC_mmodel_pkthheroine_nsbtx,
		NARC_mmodel_instructor_nsbtx,
		// @@@ NPCとりあえず
		NARC_mmodel_man2_nsbtx,
		NARC_mmodel_girl2_nsbtx,
		NARC_mmodel_boy2_nsbtx,
	};

	GF_ASSERT( tex_idx < TEX_IDX_MAX );

	return TexIdxTbl[ tex_idx ];
}

//-----------------------------------------------------------------------------
/**
 *	@brief	LCD_MAIN にポケグラを展開
 *
 *	@param	p_cap
 *	@param	pp
 *	@param	b_LCD_main
 *	@param	b_gray
 *	@param	HEAPID heapID
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
void CATS_PokeGraTrans( CATS_ACT_PTR p_cap, const MONS_INFO* p_mons, BOOL b_LCD_main, BOOL b_gray, HEAPID heapID )
{
	CATS_PokeGraTransCore( p_cap, p_mons, b_LCD_main, b_gray, heapID, TRUE );
}

void CATS_PokeGraTransEx( CATS_ACT_PTR p_cap, const MONS_INFO* p_mons, BOOL b_LCD_main, BOOL b_gray, HEAPID heapID, BOOL b_trans_pltt )
{
	CATS_PokeGraTransCore( p_cap, p_mons, b_LCD_main, b_gray, heapID, b_trans_pltt );
}

static void CATS_PokeGraTransCore( CATS_ACT_PTR p_cap, const MONS_INFO* p_mons, BOOL b_LCD_main, BOOL b_gray, HEAPID heapID, BOOL b_trans_pltt )
{
	enum { POKEGRA_TEX_SIZE = 0x20*100, };

	SOFT_SPRITE_ARC ssa;
	NNS_G2D_VRAM_TYPE vram_type = ( b_LCD_main ) ? NNS_G2D_VRAM_TYPE_2DMAIN : NNS_G2D_VRAM_TYPE_2DSUB;

	if( p_mons->MonsNo == 0 )
	{
		CATS_ObjectEnableCap( p_cap, CATS_ENABLE_FALSE );
		return;
	}

	// -- アーカイブデータ取得(ソフトウェアスプライト用）
	PokeGraArcDataGet( &ssa, p_mons->MonsNo, p_mons->Sex, PARA_FRONT, p_mons->Rare, p_mons->Form, p_mons->PsnlRnd );

	// -- OAMに変換後展開
	{
		void* char_work;
		CHANGES_INTO_DATA_RECT rect = { 0, 0, 10, 10 };

		char_work = sys_AllocMemoryLo( heapID, POKEGRA_TEX_SIZE );

		HOSAKA_PRINT( "arc_no:%d idx_chr:%d, monsNo:%d \n",ssa.arc_no, ssa.index_chr, p_mons->MonsNo );

		// TEXをOAMに変換 ※1D 64kマッピング
		Ex_ChangesInto_OAM_from_PokeTex_RC(
				ssa.arc_no, ssa.index_chr, heapID,
				&rect, char_work, p_mons->PsnlRnd, FALSE, PARA_FRONT, p_mons->MonsNo );

		OBJ_CgxChangeTrans( p_cap->act, char_work, POKEGRA_TEX_SIZE );

		if( b_trans_pltt )
		{
			OBJ_PokeGraPlttTrans( p_cap, ssa.arc_no, ssa.index_pal, b_LCD_main, b_gray, heapID );
		}

		CATS_ObjectEnableCap( p_cap, CATS_ENABLE_TRUE );

		sys_FreeMemoryEz( char_work );
	}
}

void CATS_PokeIconTrans( CATS_ACT_PTR p_cap, const MONS_INFO* p_info, u16 pltt_ofs, ARCHANDLE*p_arc, u32 vram_ofs, HEAPID HeapID )
{
	enum
	{
		POKEICON_CGX_SIZE = 0x20 * 4 * 4,
	};

	NNSG2dCharacterData* p_chr;
	u16 PokePalOfs;
	int arcIdx;
	void * buf;

	arcIdx = PokeIconCgxArcIndexGetByMonsNumber( p_info->MonsNo, 0, p_info->Form );
	buf = ArcUtil_HDL_CharDataGet( p_arc, arcIdx, FALSE, &p_chr, HeapID );

	GF_ASSERT_MSG( buf, "pokeicon arc load error \n" );

	OBJ_CgxChangeTransShiftVramOfs( p_cap->act, p_chr->pRawData, POKEICON_CGX_SIZE, vram_ofs );
	sys_FreeMemoryEz( buf );

	// パレットオフセット取得
	PokePalOfs = PokeIconPalNumGet( p_info->MonsNo, p_info->Form, 0 );

//	HOSAKA_PRINT( "[%d]PokePalOfs:%d \n",p_info->NetID, PokePalOfs );

	// パレット切替
	CATS_ObjectPaletteSetCap( p_cap, pltt_ofs + PokePalOfs );
}

//=============================================================================
/**
 *								static関数
 */
//=============================================================================
//-----------------------------------------------------------------------------
/**
 *	@brief	OBJに割り当てられているキャラデータ（CGX）を書き換える
 */
//-----------------------------------------------------------------------------
static void OBJ_CgxChangeTransShiftVramOfs( CLACT_WORK_PTR act, u8 * buf, u32 siz, u32 VramOfs )
{
	NNSG2dImageProxy * ipc;
	u32	cgx;
	NNS_G2D_VRAM_TYPE vram_type;

	vram_type = CLACT_VramTypeGet( act );
	ipc = CLACT_ImageProxyGet( act );
	cgx = NNS_G2dGetImageLocation( ipc, vram_type );
	cgx += VramOfs;

	DC_FlushRange( buf, siz );

	switch( vram_type )
	{
		case NNS_G2D_VRAM_TYPE_2DMAIN:
			GX_LoadOBJ( buf, cgx, siz );
			break;

		case NNS_G2D_VRAM_TYPE_2DSUB:
			GXS_LoadOBJ( buf, cgx, siz );
			break;

		default : GF_ASSERT(0);
	};

}

static void OBJ_CgxChangeTrans( CLACT_WORK_PTR act, u8 * buf, u32 siz )
{
	OBJ_CgxChangeTransShiftVramOfs( act, buf, siz, 0 );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	パレット上書き
 */
//-----------------------------------------------------------------------------
static void OBJ_PokeGraPlttTrans( CATS_ACT_PTR p_cap, u32 arc_no, u32 pal_idx, BOOL b_LCD_main, BOOL b_gray, HEAPID heapID )
{
	enum { POKEGRA_PAL_SIZE = 0x20, };

	u32 pal;
	NNS_G2D_VRAM_TYPE vram_type;
	PALTYPE pal_type;

	if( b_LCD_main )
	{
		vram_type = NNS_G2D_VRAM_TYPE_2DMAIN;
		pal_type = PALTYPE_MAIN_OBJ;
	}
	else
	{
		vram_type = NNS_G2D_VRAM_TYPE_2DSUB;
		pal_type = PALTYPE_SUB_OBJ;
	}

	{
		NNSG2dImagePaletteProxy * ipp;
		ipp  = CLACT_PaletteProxyGet( p_cap->act );
		pal = NNS_G2dGetImagePaletteLocation( ipp, vram_type );
	}

	ArcUtil_PalSet( arc_no, pal_idx, pal_type, pal, POKEGRA_PAL_SIZE, heapID );

	// -- グレースケール化 --
	if( b_gray )
	{
		u16* p_adr;
		p_adr = b_LCD_main ? (void*)(HW_OBJ_PLTT + pal) : (void*)(HW_DB_OBJ_PLTT + pal);
		PaletteGrayScale( p_adr, POKEGRA_PAL_SIZE );
	}
}

